/*
版权@hehung所有，转载请申明
email：1398660197@qq.com
*/
#include "app_alarm.h"
#include "app_main.h"
#include <drv/pin.h>
#include <drv/gpio_pin.h>
#include "app_display.h"
#include "app_rtc.h"
#include "app_rgb.h"
#include "app_kv.h"

/* 存储的数据，存储到KV中的数据是int型的 */
/* bit0 - bit7: 小时 */
/* bit8 - bit15: 分钟 */
/* bit16 - bit22: 星期一到星期天使能状态 */
/* bit24: 使能状态 */
#define ALARM_HOUR_MASK                   (0xFFU)
#define ALARM_HOUR_MASK_SHIFT             (0U)
#define ALARM_MIN_MASK                    (0xFF00U)
#define ALARM_MIN_MASK_SHIFT              (8U)
#define ALARM_WEEK_MASK                   (0x7F0000U)
#define ALARM_WEEK_MASK_SHIFT             (16U)
#define ALARM_EN_MASK                     (0x1000000U)
#define ALARM_EN_MASK_SHIFT               (24U)

/* RTC 闹钟只能设置一个，不满足需求，所以设置软件闹钟 */
static aos_task_t alarm_task_h;    /* Clock Alarm task handle */
static uint16_t alarm_task_cycle_ms = ALARM_RNU_CYCLE;   
/* 闹钟配置信息 */
static e_AlarmType alarm_list[ALARM_NUM_MAX] = 
{
	[0 ... ALARM_NUM_MAX-1] = {0, 0, 0, 0}
};
/* 闹钟警报标志 */
static e_AlarmWarningType alarmWarning_flg = {0, 0};


static void Alarm_TaskEntry(void *arg);
static void Alarm_Check(void);
static void Alarm_Running(void);
static void Alarm_Init(void);
static void Alarm_SaveClock(uint8_t num);


/* 闹钟函数初始化 */
void Alarm_TaskInit(void)
{
	int task_s;
	 
	task_s = aos_task_new_ext(&alarm_task_h,
								"alarm_task", 
								Alarm_TaskEntry, 
								NULL, 
								1024, 
								1);
	if (0 == task_s)
	{
		printf("APP_ALARM Task create success\r\n");
	}
	else
	{
		printf("APP_ALARM Task create failed\r\n");
	}
}

/* 闹钟函数任务入口 */
static void Alarm_TaskEntry(void *arg)
{
    /* 导入KV中存储的闹钟数据 */
	Alarm_Init();
    
    while (1) 
	{
		Alarm_Check();
		Alarm_Running();
		
		aos_msleep(alarm_task_cycle_ms);
    }
}

/* 闹钟警报逻辑 */
static void Alarm_Running(void)
{
	if (ALARM_WARNING_ON == alarmWarning_flg.alarm_active)
	{
		/* 闹钟最多响 ALARM_WARNING_HOLD_THD s 久就会退出*/
		if (alarmWarning_flg.alarm_run_t > ALARM_WARNING_HOLD_THD)
		{
			/* 停止闹钟 */
			alarmWarning_flg.alarm_active = ALARM_WARNING_OFF;
		}
		else
		{
			alarmWarning_flg.alarm_run_t ++;
		}
	}
	else
	{
		alarmWarning_flg.alarm_run_t = 0U;
	}
}

/* 闹钟报警监测逻辑 */
static void Alarm_Check(void)
{
	uint8_t i;
	csi_rtc_time_t cur_t;
	uint8_t weekday;
	static uint8_t alarm_h_bk[ALARM_NUM_MAX];    /* 备份本次闹钟激活的时间 - 秒 */
	static uint8_t alarm_m_bk[ALARM_NUM_MAX];    /* 备份本次闹钟激活的时间 - 分 */

	/* 获取当前时间 */
	cur_t = Rtc_GetCurrentTime();
	/* 泰勒公式计算星期 */
	weekday = Rtc_CalculateWeekday(cur_t.tm_year+1900, cur_t.tm_mon+1, cur_t.tm_mday);

	for (i = 0; i < ALARM_NUM_MAX; i++)
	{
		/* 设置了星期 */
		if ((alarm_list[i].alarm_h == cur_t.tm_hour) &&  /* 当前小时满足 */
			(alarm_list[i].alarm_m == cur_t.tm_min) &&   /* 当前分钟满足 */
			(alarm_list[i].alarm_en) &&             /* 闹钟已经使能 */
			((((alarm_list[i].alarm_wk_bit&ALARM_MONDAY_EN)) && (weekday == 1)) ||     /* 星期一的闹钟使能了 */
			 (((alarm_list[i].alarm_wk_bit&ALARM_TUESDAY_EN)) && (weekday == 2)) ||    /* 星期二的闹钟使能了 */
			 (((alarm_list[i].alarm_wk_bit&ALARM_WEDNESDAY_EN)) && (weekday == 3)) ||  /* 星期三的闹钟使能了 */
			 (((alarm_list[i].alarm_wk_bit&ALARM_THURSDAY_EN)) && (weekday == 4)) ||   /* 星期四的闹钟使能了 */
			 (((alarm_list[i].alarm_wk_bit&ALARM_FIRDAY_EN)) && (weekday == 5)) ||     /* 星期五的闹钟使能了 */
			 (((alarm_list[i].alarm_wk_bit&ALARM_SATURDAY_EN)) && (weekday == 6)) ||   /* 星期六的闹钟使能了 */
			 (((alarm_list[i].alarm_wk_bit&ALARM_SUNDAY_EN)) && (weekday == 0))) &&    /* 星期天的闹钟使能了 */
			(ALARM_WARNING_OFF == alarmWarning_flg.alarm_actived)    /* 闹钟还没有报警 */
		)
		{
			alarm_h_bk[i] = alarm_list[i].alarm_h;
			alarm_m_bk[i] = alarm_list[i].alarm_m;
			alarmWarning_flg.alarm_actived = ALARM_WARNING_ON;
			alarmWarning_flg.alarm_active = ALARM_WARNING_ON;    /* 激活闹钟 */
			alarmWarning_flg.alarm_run_t = 0U;

			/* 不退出避免还有单个闹钟触发之后不能关闭 */
			// break;
		}
		/* 未设置星期，闹钟只工作一次 */
		else if ((alarm_list[i].alarm_h == cur_t.tm_hour) &&  /* 当前小时满足 */
			(alarm_list[i].alarm_m == cur_t.tm_min) &&   /* 当前分钟满足 */
			(alarm_list[i].alarm_en) &&             /* 闹钟已经使能 */
			(ALARM_WARNING_OFF == alarmWarning_flg.alarm_actived)    /* 闹钟还没有报警 */
		)
		{
			alarm_list[i].alarm_en = 0;

			alarm_h_bk[i] = alarm_list[i].alarm_h;
			alarm_m_bk[i] = alarm_list[i].alarm_m;
			alarmWarning_flg.alarm_actived = ALARM_WARNING_ON;
			alarmWarning_flg.alarm_active = ALARM_WARNING_ON;    /* 激活闹钟 */
			alarmWarning_flg.alarm_run_t = 0U;

			/* 不退出避免还有单个闹钟触发之后不能关闭 */
			// break;
		}

		/* 已经过了闹钟激活的时间 并且 闹钟已经被激活过了 */
		if (((alarm_h_bk[i] != alarm_list[i].alarm_h) || (alarm_m_bk[i] != alarm_list[i].alarm_m)) &&
			(ALARM_WARNING_ON == alarmWarning_flg.alarm_actived))
		{
			/* 清空闹钟激活过的标志便于记录下一次闹钟激活处理 */
			alarmWarning_flg.alarm_actived = ALARM_WARNING_OFF;
		}
	}
}

/* 导入KV中存储的闹钟数据 */
static void Alarm_Init(void)
{
	const e_KvSaveType kv_clock[10] = 
	{	
		KV_CLOCK_1,
		KV_CLOCK_2,
		KV_CLOCK_3,
		KV_CLOCK_4,
		KV_CLOCK_5,
		KV_CLOCK_6,
		KV_CLOCK_7,
		KV_CLOCK_8,
		KV_CLOCK_9,
		KV_CLOCK_10
	};
	uint8_t i;
	int read_data;

	for (i=0; i<ALARM_NUM_MAX; i++)
	{
		// printf("\n Clock Save mask:%d - %d \n", i, Kv_GetSaveStatus(kv_clock[i]));
		/* 表示某一个闹钟被存储过 */
		if (1 == Kv_GetSaveStatus(kv_clock[i]))
		{
			/* 读取存储的值 */
			read_data = Kv_ReadData(kv_clock[i]);
			/* bit0 - bit7: 小时 */
			/* bit8 - bit15: 分钟 */
			/* bit16 - bit22: 星期一到星期天使能状态 */
			/* bit23: 使能状态 */
			// printf("\n Clock Read Data:%d - %x\n", i, read_data);
			alarm_list[i].alarm_h = (((uint32_t)read_data)&ALARM_HOUR_MASK) >> ALARM_HOUR_MASK_SHIFT;
			alarm_list[i].alarm_m = (((uint32_t)read_data)&ALARM_MIN_MASK) >> ALARM_MIN_MASK_SHIFT;
			alarm_list[i].alarm_en = (((uint32_t)read_data)&ALARM_EN_MASK) >> ALARM_EN_MASK_SHIFT;
			alarm_list[i].alarm_wk_bit = (((uint32_t)read_data)&ALARM_WEEK_MASK) >> ALARM_WEEK_MASK_SHIFT;
			// printf("%d-%d-%d-%d\n", alarm_list[i].alarm_h, alarm_list[i].alarm_m, alarm_list[i].alarm_en, alarm_list[i].alarm_wk_bit);
		}
	}
}

/* 存储数据到KV中 */
static void Alarm_SaveClock(uint8_t num)
{
	const e_KvSaveType kv_clock[10] = 
	{	
		KV_CLOCK_1,
		KV_CLOCK_2,
		KV_CLOCK_3,
		KV_CLOCK_4,
		KV_CLOCK_5,
		KV_CLOCK_6,
		KV_CLOCK_7,
		KV_CLOCK_8,
		KV_CLOCK_9,
		KV_CLOCK_10
	};
	int write_data;

	write_data = (alarm_list[num].alarm_h << (ALARM_HOUR_MASK_SHIFT)) |
					(alarm_list[num].alarm_m << (ALARM_MIN_MASK_SHIFT)) |
					(alarm_list[num].alarm_wk_bit << (ALARM_WEEK_MASK_SHIFT)) |
					(alarm_list[num].alarm_en << (ALARM_EN_MASK_SHIFT));
	Kv_WriteData(kv_clock[num], write_data);
	// printf("\n Clock Save Data:%d - %x \n", num, write_data);
}

/* 获取当前配置的闹钟信息
	num:0-9 表示第1-10个闹钟
 */
e_AlarmType Alarm_GetAlarmTime(uint8_t num)
{
	return (num < 10) ? (alarm_list[num]) : (alarm_list[0]);
}

/* 设置闹钟信息
	num：0-9 表示第1-10个闹钟
	time：表示要设置的第num个闹钟的信息
 */
void Alarm_SetAlarmTime(uint8_t num, e_AlarmType time)
{
	alarm_list[num] = time;
	Alarm_SaveClock(num);
}

/* 停止警报 */
void Alarm_StopWarning(void)
{
	alarmWarning_flg.alarm_active = ALARM_WARNING_OFF;
}

uint8_t Alarm_GetalarmFlag(void)
{
	return alarmWarning_flg.alarm_active;
}

